using Net35.Xrm.Sdk.Query;
using System;
using System.Reflection;
using System.Security.Permissions;

namespace Net35.Xrm.Sdk.Client
{
	public class OrganizationServiceProxy : ServiceProxy<IOrganizationService>, IOrganizationService
	{
		private string _xrmSdkAssemblyFileVersion;
		internal bool OfflinePlayback
		{
			get;
			set;
		}
		public Guid CallerId
		{
			get;
			set;
		}
		internal int LanguageCodeOverride
		{
			get;
			set;
		}
		public string SyncOperationType
		{
			get;
			set;
		}
		internal string ClientAppName
		{
			get;
			set;
		}
		internal string ClientAppVersion
		{
			get;
			set;
		}
		public string SdkClientVersion
		{
			get;
			set;
		}
		internal OrganizationServiceProxy()
		{
		}
		public OrganizationServiceProxy(System.Uri uri, System.Uri homeRealmUri, System.ServiceModel.Description.ClientCredentials clientCredentials, System.ServiceModel.Description.ClientCredentials deviceCredentials) : base(uri, homeRealmUri, clientCredentials, deviceCredentials)
		{
		}
		public OrganizationServiceProxy(IServiceConfiguration<IOrganizationService> serviceConfiguration, SecurityTokenResponse securityTokenResponse) : base(serviceConfiguration, securityTokenResponse)
		{
		}
		public OrganizationServiceProxy(IServiceConfiguration<IOrganizationService> serviceConfiguration, System.ServiceModel.Description.ClientCredentials clientCredentials) : base(serviceConfiguration, clientCredentials)
		{
		}
		public OrganizationServiceProxy(IServiceManagement<IOrganizationService> serviceManagement, SecurityTokenResponse securityTokenResponse) : this(serviceManagement as IServiceConfiguration<IOrganizationService>, securityTokenResponse)
		{
		}
		public OrganizationServiceProxy(IServiceManagement<IOrganizationService> serviceManagement, System.ServiceModel.Description.ClientCredentials clientCredentials) : this(serviceManagement as IServiceConfiguration<IOrganizationService>, clientCredentials)
		{
		}
		public void EnableProxyTypes()
		{
			ClientExceptionHelper.ThrowIfNull(base.ServiceConfiguration, "ServiceConfiguration");
			OrganizationServiceConfiguration organizationServiceConfiguration = base.ServiceConfiguration as OrganizationServiceConfiguration;
			ClientExceptionHelper.ThrowIfNull(organizationServiceConfiguration, "orgConfig");
			organizationServiceConfiguration.EnableProxyTypes();
		}
		public void EnableProxyTypes(Assembly assembly)
		{
			ClientExceptionHelper.ThrowIfNull(assembly, "assembly");
			ClientExceptionHelper.ThrowIfNull(base.ServiceConfiguration, "ServiceConfiguration");
			OrganizationServiceConfiguration organizationServiceConfiguration = base.ServiceConfiguration as OrganizationServiceConfiguration;
			ClientExceptionHelper.ThrowIfNull(organizationServiceConfiguration, "orgConfig");
			organizationServiceConfiguration.EnableProxyTypes(assembly);
		}
		[PermissionSet(SecurityAction.Demand, Unrestricted = true)]
		internal string GetXrmSdkAssemblyFileVersion()
		{
			if (string.IsNullOrEmpty(this._xrmSdkAssemblyFileVersion))
			{
				string[] array = new string[]
				{
					"Microsoft.Xrm.Sdk.dll"
				};
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				string[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					string value = array2[i];
					Assembly[] array3 = assemblies;
					for (int j = 0; j < array3.Length; j++)
					{
						Assembly assembly = array3[j];
						if (assembly.ManifestModule.Name.Equals(value, StringComparison.OrdinalIgnoreCase))
						{
							this._xrmSdkAssemblyFileVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
						}
					}
				}
			}
			return this._xrmSdkAssemblyFileVersion;
		}
		protected internal virtual Guid CreateCore(Entity entity)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						return base.ServiceChannel.Channel.Create(entity);
					}
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
			return Guid.Empty;
		}
		protected internal virtual Entity RetrieveCore(string entityName, Guid id, ColumnSet columnSet)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						return base.ServiceChannel.Channel.Retrieve(entityName, id, columnSet);
					}
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
			return null;
		}
		protected internal virtual void UpdateCore(Entity entity)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						base.ServiceChannel.Channel.Update(entity);
					}
					break;
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
		}
		protected internal virtual void DeleteCore(string entityName, Guid id)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						base.ServiceChannel.Channel.Delete(entityName, id);
					}
					break;
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
		}
		protected internal virtual OrganizationResponse ExecuteCore(OrganizationRequest request)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						return base.ServiceChannel.Channel.Execute(request);
					}
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
			return null;
		}
		protected internal virtual void AssociateCore(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						base.ServiceChannel.Channel.Associate(entityName, entityId, relationship, relatedEntities);
					}
					break;
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
		}
		protected internal virtual void DisassociateCore(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						base.ServiceChannel.Channel.Disassociate(entityName, entityId, relationship, relatedEntities);
					}
					break;
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
		}
		protected internal virtual EntityCollection RetrieveMultipleCore(QueryBase query)
		{
			bool? retry = null;
			do
			{
				bool forceClose = false;
				try
				{
					using (new OrganizationServiceContextInitializer(this))
					{
						return base.ServiceChannel.Channel.RetrieveMultiple(query);
					}
				}
				catch (System.ServiceModel.Security.MessageSecurityException messageSecurityException)
				{
					forceClose = true;
					retry = base.ShouldRetry(messageSecurityException, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.EndpointNotFoundException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (TimeoutException)
				{
					forceClose = true;
					retry = new bool?(base.HandleFailover(retry));
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch (System.ServiceModel.FaultException<OrganizationServiceFault> faultException)
				{
					forceClose = true;
					retry = base.HandleFailover(faultException.Detail, retry);
					if (!retry.GetValueOrDefault())
					{
						throw;
					}
				}
				catch
				{
					forceClose = true;
					throw;
				}
				finally
				{
					this.CloseChannel(forceClose);
				}
			}
			while (retry.HasValue && retry.Value);
			return null;
		}
		public Guid Create(Entity entity)
		{
			return this.CreateCore(entity);
		}
		public Entity Retrieve(string entityName, Guid id, ColumnSet columnSet)
		{
			return this.RetrieveCore(entityName, id, columnSet);
		}
		public void Update(Entity entity)
		{
			this.UpdateCore(entity);
		}
		public void Delete(string entityName, Guid id)
		{
			this.DeleteCore(entityName, id);
		}
		public OrganizationResponse Execute(OrganizationRequest request)
		{
			return this.ExecuteCore(request);
		}
		public void Associate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
		{
			this.AssociateCore(entityName, entityId, relationship, relatedEntities);
		}
		public void Disassociate(string entityName, Guid entityId, Relationship relationship, EntityReferenceCollection relatedEntities)
		{
			this.DisassociateCore(entityName, entityId, relationship, relatedEntities);
		}
		public EntityCollection RetrieveMultiple(QueryBase query)
		{
			return this.RetrieveMultipleCore(query);
		}		
	}
}